<?php

namespace App\Models;

use App\Clients\CrmClient;
use App\Jobs\ClueCreatedJob;
use Carbon\Carbon;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class Clue extends Model
{
    use HasFactory;
    use HasDateTimeFormatter;

    const TYPE_TRANSFER = 1;
    const TYPE_API = 2;
    const TYPE_GRAB = 3;


    const JU_LIANG = 1;
    const BAI_DU = 2;
    const KUAI_SHOU = 3;
    const TENG_XUN = 4;
    const OPPO = 5;
    const VIVO = 6;
    const UC = 7;
    const GZH = 8;

    const SOURCE_FIELDS = [
        self::JU_LIANG => '头条',
        self::BAI_DU => '百度',
        self::KUAI_SHOU => '快手',
        self::TENG_XUN => '腾讯',
        self::OPPO => 'OPPO',
        self::VIVO => 'VIVO',
        self::UC => 'UC',
        self::GZH => '公众号二维码',
    ];

    const A_STATUS_UN_ACTION = 0;
    const A_STATUS_ARCHIVE_SUCCESS = 1;
    const A_STATUS_ARCHIVE_REPEAT = 2;
    const A_STATUS_ARCHIVE_ERROR = 3;

    const A_STATUS_OPTIONS = [
        self::A_STATUS_UN_ACTION => '未操作',
        self::A_STATUS_ARCHIVE_SUCCESS => '建档成功',
        self::A_STATUS_ARCHIVE_REPEAT => '已被建档',
        self::A_STATUS_ARCHIVE_ERROR => '建档失败',
    ];

    const CRM_STATUS_UN_CHECK = 0;
    const CRM_STATUS_UN_ARCHIVE = 1;
    const CRM_STATUS_REPEAT = 2;

    const CRM_STATUS_OPTIONS = [
        self::CRM_STATUS_UN_CHECK => '未查询',
        self::CRM_STATUS_UN_ARCHIVE => '未建档',
        self::CRM_STATUS_REPEAT => '重复表单(已建档)',
    ];

    protected $fillable = [
        'name',
        'phone',
        'source',
        'url',
        'site_name',
        'ad_name',
        'ad_id',
        'remark',
        'ip',
        'type',
        'location',
        'question_data',
        'post_date',
        'origin_data',
        'uuid',
        'user_id',
        'tag_id',
        'dispatch_date',
        'project_id',
        'rule_id',
        'media_id',
        'status',
        'no_dispatch',
        'a_status',
        'crm_status',
        'log',
        'crm_response',

        // 2023-6-8 添加附件功能
        'files',
    ];

    protected $casts = [
        'question_data' => 'json',
        'files' => 'json',
        'origin_data' => 'json',
        'crm_response' => 'json'
    ];

    public function user()
    {
        return $this->belongsTo(Administrator::class, 'user_id', 'id');
    }

    public function tag()
    {
        return $this->belongsTo(Tag::class, 'tag_id', 'id');
    }

    public function rule()
    {
        return $this->belongsTo(DispatchRule::class, 'rule_id', 'id');
    }


    /**
     * 为传入的 表单 ID 修改  分配时间
     *
     * @param $id   array|string|number
     * @param $date string|Carbon
     */
    public static function setDispatchDate($id, $date)
    {
        static::query()
            ->whereIn('id', (array)$id)
            ->update([
                'dispatch_date' => $date
            ]);
    }

    public static function fixPostDate()
    {
        DB::table('clues')
            ->whereNull('post_date')
            ->update([
                "post_date" => DB::raw("`created_at`")
            ]);
    }

    public function mapToDispatchOfCheckRule()
    {
        $rule = DispatchRule::checkRule($this);
        if ($rule) {
            $user = UserGroup::getGroupDispatchUser($rule['group_id']);

            if ($user) {
                $this->mapToDispatchOfToUser($user, false);
            }
            $this->rule_id = $rule->id;
            $this->save();
        }
        Log::debug("分配结果 :", [
            '线索ID' => $this->id,
            '线索电话' => $this->phone,
            '规则ID' => $this->rule_id,
            '用户ID' => $this->user_id,
        ]);
    }

    public function mapToDispatchOfCheckClueIsTodayDispatched($less = true)
    {
        if ($this->user_id && $this->dispatch_date) {
            $date = Carbon::parse($this->dispatch_date);
            if ($date->isToday()) {
                if ($less) {
                    $key = "{$date->toDateString()}.{$this->user_id}";
                    Administrator::userForgetOne($key);
                }
                return true;
            }
        }
        return false;
    }

    public function mapToDispatchOfToUser($user, $save = true)
    {
        $this->mapToDispatchOfCheckClueIsTodayDispatched();
        $this->user_id = $user['id'];
        $this->dispatch_date = now();
        $key = data_get($user, 'cache_key');
        if (!$key)
            $key = "{$this->dispatch_date->toDateString()}.$this->user_id";

        $user->userGetOne($key);

        if ($save)
            $this->save();
    }

    public function mapToProjectOfCheck()
    {
        $project = Project::checkProject($this);
        if ($project) {
            $this->project_id = $project->id;
            $this->save();
        }
    }

    public function checkCrmStatus()
    {
        $r = CrmClient::checkPhoneIsArchive($this->phone);
        $this->crm_status = $r ? self::CRM_STATUS_REPEAT : self::CRM_STATUS_UN_ARCHIVE;
        $this->save();
    }

    public static function redispatchOverflowClue()
    {
        $start = today()->addDays(-7)->toDateTimeString();
        $clues = static::query()
            ->where('post_date', '>', $start)
            ->where('no_dispatch', 0)
            ->whereNull('user_id')->get();
        foreach ($clues as $clue) {
            $clue->mapToDispatchOfCheckRule();
        }
    }

    /**
     * @param $url
     * @return int|null
     */
    public static function getSourceByUrl($url): ?int
    {
        if (!$url)
            return null;

        if (preg_match("/47\.104\.65\.130:8028/", $url))
            return self::JU_LIANG;


        if (preg_match("/tt\.(.*?)xxl/", $url))
            return self::JU_LIANG;

        if (preg_match("/dy\.(.*?)xxl/", $url))
            return self::JU_LIANG;
        if (preg_match("/uc\.(.*?)xxl/", $url))
            return self::UC;
        if (preg_match("/ks\.(.*?)xxl/", $url))
            return self::KUAI_SHOU;
        if (preg_match("/tx\.(.*?)xxl/", $url))
            return self::TENG_XUN;
        if (preg_match("/vivo\.(.*?)xxl/", $url))
            return self::VIVO;
        if (preg_match("/(bd|baidu)\.(.*?)xxl/", $url))
            return self::BAI_DU;
        if (preg_match("/oppo\.(.*?)xxl/", $url))
            return self::OPPO;

        return null;
    }

    public static function test()
    {
        $clue = static::query()->orderBy('id', 'desc')->first();
        for ($i = 0; $i < 10; $i++) {
            ClueCreatedJob::dispatch($clue)->onQueue('clue_created');
        }
    }
}
